﻿

namespace Mulala.Cavan.Domain.MainBoundedContext.ProprietorModule
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Mulala.Cavan.Domain.Seedwork;
    using Mulala.Cavan.Domain.MainBoundedContext.SecurityModule;
    using Mulala.Cavan.Domain.MainBoundedContext.DictionaryModule;
    using Mulala.Cavan.Domain.MainBoundedContext.ConsignModule;
    using Mulala.Cavan.Domain.MainBoundedContext.NannyModule;
    using Mulala.Cavan.Domain.MainBoundedContext.CorporationModule;
    using Mulala.Cavan.Domain.MainBoundedContext.Setting;
    using Mulala.Cavan.Domain.MainBoundedContext.AttachmentModule;
using Mulala.Cavan.Domain.MainBoundedContext.InformationModule;

    [Serializable]
    public class Proprietor : Persistent
    {
        public virtual UserAccount UserAccount { get; set; }
        public virtual string Name { get; set; }
        public virtual bool NamePrivacy { get; set; }
        public virtual string ContactEmail { get; set; }
        public virtual bool ContactEmailPrivacy { get; set; }
        public virtual Area Area { get; set; }
        public virtual string Telephone { get; set; }
        public virtual bool TelephonePrivacy { get; set; }
        public virtual string Address { get; set; }
        public virtual bool AddressPrivacy { get; set; }
        public virtual string Introduce { get; set; }
        public virtual IList<Consign> Consigns { get; set; }
        public virtual ProprietorStatus ProprietorStatus { get; set; }
        public virtual IList<Attachment> Attachments { get; set; }

        public virtual BoolGenericResult<Proprietor> ModifyInfo(
                                                        string name,
                                                        bool namePrivacy,
                                                        string contactEmail,
                                                        bool contactEmailPrivacy,
                                                        Area area,
                                                        string telephone,
                                                        bool telephonePrivacy,
                                                        string address,
                                                        bool addressPrivacy,
                                                        string introduce)
        {
            if (area == null)
            {
                throw new ArgumentException("");
            }

            BoolGenericResult<Proprietor> result = new BoolGenericResult<Proprietor>();

            this.Name = name;
            this.NamePrivacy = namePrivacy;
            this.ContactEmail = contactEmail;
            this.ContactEmailPrivacy = contactEmailPrivacy;
            this.Area = area;
            this.Telephone = telephone;
            this.Address = address;
            this.AddressPrivacy = addressPrivacy;
            this.Introduce = introduce;

            this.ProprietorStatus.BasicInfoStatus = ProprietorIdentifier.CheckedStatus.Modified;

            result.Object = this;

            return result;
        }

        public virtual BoolGenericResult<Attachment> ModifyAvatar(
                                                        string fileUrl,
                                                        string fileName)
        {
            BoolGenericResult<Attachment> result = new BoolGenericResult<Attachment>();
            Attachment avatar = this.Attachments.FirstOrDefault(a => a.OwnerID == this.ID && a.AttachmentGroup == AttachmentIdentifier.AttachmentGroup.ProprietorAvatar);
            avatar.FileUrl = fileUrl;
            avatar.FileName = fileName;
            result.Object = avatar;

            return result;
        }

        public virtual BoolGenericResult<Consign> PublishConsign(
                                                        string name,
                                                        int age,
                                                        int sex,
                                                        Area area,
                                                        string address,
                                                        int experience,
                                                        long necessarySkill,
                                                        long firstSkill,
                                                        long secondSkill,
                                                        long thirdSkill,
                                                        ConsignIdentifier.MarriedNeed isMarried,
                                                        ConsignIdentifier.HasChildrenNeed hasChildren,
                                                        int degree,
                                                        int salary,
                                                        ConsignIdentifier.ConsignType type,
                                                        ConsignIdentifier.ConsignRange range,
                                                        ConsignIdentifier.ConsignStatus consignStatus,
                                                        string contact,
                                                        string telephone,
                                                        string remark)
        {
            BoolGenericResult<Consign> result = new BoolGenericResult<Consign>();

            Consign consign = ConsignFactory.CreateConsign(this, name, age, sex, area, address, experience, necessarySkill,
                                                firstSkill, secondSkill, thirdSkill, isMarried, hasChildren, degree,
                                                salary, 0, DateTime.Now.AddMonths(Project.Settings.DefaultConsignValidMonth), type, range, consignStatus, contact, telephone,
                                                remark, ConsignIdentifier.CheckedStatus.UnChecked, DateTime.Parse(Project.Settings.DefaultTime), DateTime.Parse(Project.Settings.DefaultTime),
                                                null, DateTime.Now, this.UserAccount.Name);


            result.Object = consign;

            return result;
        }

        public virtual BoolGenericResult<Consign> PublishConsign(
                                                        string name,
                                                        int age,
                                                        int sex,
                                                        Area area,
                                                        string address,
                                                        int experience,
                                                        long necessarySkill,
                                                        long firstSkill,
                                                        long secondSkill,
                                                        long thirdSkill,
                                                        ConsignIdentifier.MarriedNeed isMarried,
                                                        ConsignIdentifier.HasChildrenNeed hasChildren,
                                                        int degree,
                                                        int salary,
                                                        ConsignIdentifier.ConsignType type,
                                                        ConsignIdentifier.ConsignRange range,
                                                        ConsignIdentifier.ConsignStatus consignStatus,
                                                        string contact,
                                                        string telephone,
                                                        string remark,
                                                        IList<ConsignBidder> consignBidders)
        {
            if (area == null)
            {
                throw new ArgumentException("");
            }

            BoolGenericResult<Consign> result = new BoolGenericResult<Consign>();

            int bidCount = 0;
            if (null != consignBidders && consignBidders.Count > 0)
            {
                bidCount = consignBidders.Count;
            }
            Consign consign = ConsignFactory.CreateConsign(this, name, age, sex, area, address, experience, necessarySkill,
                                                firstSkill, secondSkill, thirdSkill, isMarried, hasChildren, degree,
                                                salary, bidCount, DateTime.Now.AddMonths(Project.Settings.DefaultConsignValidMonth), type, range, consignStatus, contact, telephone,
                                                remark, ConsignIdentifier.CheckedStatus.UnChecked, DateTime.Parse(Project.Settings.DefaultTime), DateTime.Parse(Project.Settings.DefaultTime),
                                                consignBidders, DateTime.Now, this.UserAccount.Name);



            result.Object = consign;

            return result;
        }

        public virtual BoolGenericResult<Consign> ModifyConsign(
                                                Consign consign,
                                                string name,
                                                int age,
                                                int sex,
                                                Area area,
                                                string address,
                                                int experience,
                                                long necessarySkill,
                                                long firstSkill,
                                                long secondSkill,
                                                long thirdSkill,
                                                ConsignIdentifier.MarriedNeed isMarried,
                                                ConsignIdentifier.HasChildrenNeed hasChildren,
                                                int degree,
                                                int salary,
                                                ConsignIdentifier.ConsignType type,
                                                ConsignIdentifier.ConsignRange range,
                                                ConsignIdentifier.ConsignStatus consignStatus,
                                                string contact,
                                                string telephone,
                                                string remark)
        {
            if (consign == null)
            {
                throw new ArgumentException("");
            }

            if (area == null)
            {
                throw new ArgumentException("");
            }

            BoolGenericResult<Consign> result = new BoolGenericResult<Consign>();
            consign.Name = name;
            consign.Age = age;
            consign.Sex = sex;
            consign.Area = area;
            consign.Address = address;
            consign.Experience = experience;
            consign.NecessarySkill = necessarySkill;
            consign.FirstSkill = firstSkill;
            consign.SecondSkill = secondSkill;
            consign.ThirdSkill = thirdSkill;
            consign.IsMarried = isMarried;
            consign.HasChildren = hasChildren;
            consign.Degree = degree;
            consign.Salary = salary;
            consign.Type = type;
            consign.Range = range;
            consign.ConsignStatus = consignStatus;
            consign.Contact = contact;
            consign.Telephone = telephone;
            consign.Remark = remark;

            result.Object = consign;

            return result;
        }

        public virtual BoolGenericResult<Consign> CancelConsign(Consign consign)
        {
            if (consign == null)
            {
                throw new ArgumentException("");
            }

            BoolGenericResult<Consign> result = new BoolGenericResult<Consign>();

            consign.ConsignStatus = ConsignIdentifier.ConsignStatus.IsCanceled;
            if (null != consign.ConsignBidders && consign.ConsignBidders.Count > 0)
            {
                foreach (ConsignBidder cb in consign.ConsignBidders)
                {
                    cb.ConsignBidderStatus = ConsignIdentifier.ConsignBidderStatus.IsCanceled;
                }
            }

            result.Object = consign;

            return result;
        }

        public virtual BoolGenericResult<Consign> RePublishConsign(Consign consign)
        {
            if (consign == null)
            {
                throw new ArgumentException("");
            }

            BoolGenericResult<Consign> result = new BoolGenericResult<Consign>();
            consign.ConsignStatus = ConsignIdentifier.ConsignStatus.IsBidding;
            if (null != consign.ConsignBidders && consign.ConsignBidders.Count > 0)
            {
                foreach (ConsignBidder cb in consign.ConsignBidders)
                {
                    cb.ConsignBidderStatus = ConsignIdentifier.ConsignBidderStatus.IsNew;
                }
            }
            result.Object = consign;
            return result;
        }

        public virtual BoolGenericResult<Consign> DeleteConsign(Consign consign)
        {
            if (consign == null)
            {
                throw new ArgumentException("");
            }

            BoolGenericResult<Consign> result = new BoolGenericResult<Consign>();

            if (consign.ConsignStatus == ConsignIdentifier.ConsignStatus.IsClosed)
            {
                result.IsSuccess = false;
                result.Messages.Add("已委托成功,不予删除");
                return result;
            }
            if (null != consign.ConsignBidders && consign.ConsignBidders.Count > 0)
            {
                foreach (ConsignBidder cb in consign.ConsignBidders)
                {
                    cb.ConsignBidderStatus = ConsignIdentifier.ConsignBidderStatus.IsCanceled;
                }
            }

            result.Object = consign;

            return result;
        }

        public virtual BoolGenericResult<Consign> LockConsign(Consign consign)
        {
            if (consign == null)
            {
                throw new ArgumentException("");
            }

            BoolGenericResult<Consign> result = new BoolGenericResult<Consign>();
            consign.ConsignStatus = ConsignIdentifier.ConsignStatus.IsLocked;
            result.Object = consign;

            return result;
        }

        public virtual BoolGenericResult<Consign> UnLockConsign(Consign consign)
        {
            if (consign == null)
            {
                throw new ArgumentException("");
            }

            BoolGenericResult<Consign> result = new BoolGenericResult<Consign>();
            consign.ConsignStatus = ConsignIdentifier.ConsignStatus.IsBidding;
            result.Object = consign;

            return result;
        }

        public virtual BoolGenericResult<ConsignBidder> DesignateNanny(Nanny nanny, Consign consign)
        {
            if (consign == null)
            {
                throw new ArgumentException("");
            }

            BoolGenericResult<ConsignBidder> result = new BoolGenericResult<ConsignBidder>();

            ConsignBidder consignBidder = ConsignBidderFactory.CreateConsignBidder(consign, nanny, nanny.Corporation, ConsignIdentifier.ConsignBidderStatus.IsNew, true, DateTime.Now,
                this.UserAccount.Name);
            result.Object = consignBidder;

            return result;
        }

        public virtual BoolGenericResult<ConsignBidder> AcceptBidder(Nanny nanny, Consign consign)
        {
            if (consign == null)
            {
                throw new ArgumentException("");
            }

            if (nanny == null)
            {
                throw new ArgumentException("");
            }

            BoolGenericResult<ConsignBidder> result = new BoolGenericResult<ConsignBidder>();
            IList<ConsignBidder> consignBidders = consign.ConsignBidders;
            ConsignBidder consignBidder = consignBidders.FirstOrDefault(c => c.Bidder.ID == nanny.ID);
            consignBidder.ConsignBidderStatus = ConsignIdentifier.ConsignBidderStatus.IsAccepted;
            consign.ConsignStatus = ConsignIdentifier.ConsignStatus.IsClosed;

            result.Object = consignBidder;

            return result;
        }

        public virtual BoolGenericResult<CorporationComment> CommentCorporation(
                                                                    Corporation corporation,
                                                                    string content,
                                                                    int infoAuthentic,
                                                                    int serviceAttitude,
                                                                    int nannyQuality)
        {
            if (corporation == null)
            {
                throw new ArgumentException("");
            }

            BoolGenericResult<CorporationComment> result = new BoolGenericResult<CorporationComment>();
            CorporationComment corporationComment = CorporationCommentFactory.CreateCorporationComment(corporation, this, content, infoAuthentic, serviceAttitude, nannyQuality, false,
                CorporationIdentifier.CheckedStatus.UnChecked, DateTime.Now, this.UserAccount.Name);

            result.Object = corporationComment;

            return result;
        }

        public virtual BoolGenericResult<NannyComment> CommentNanny(
                                                            Nanny nanny,
                                                            string content,
                                                            int infoAuthentic,
                                                            int workProficient,
                                                            int personalIntegrity,
                                                            int personalCharm)
        {
            if (nanny == null)
            {
                throw new ArgumentException("");
            }

            BoolGenericResult<NannyComment> result = new BoolGenericResult<NannyComment>();
            NannyComment nannyComment = NannyCommentFactory.CreateNannyComment(nanny, this, content, infoAuthentic, workProficient, personalIntegrity, personalCharm, false,
                NannyIdentifier.CheckedStatus.UnChecked, DateTime.Now, this.UserAccount.Name);

            result.Object = nannyComment;

            return result;
        }

        public virtual BoolGenericResult<UserMessage> LeaveMessage(
                                                            UserAccount ownerUserAccount,
                                                            string content)
        {
            if (ownerUserAccount == null)
            {
                throw new ArgumentException("");
            }

            BoolGenericResult<UserMessage> result = new BoolGenericResult<UserMessage>();
            UserMessage userMessage = UserMessageFactory.CreateUserMessage(ownerUserAccount, content, 0, 0, this.UserAccount, false, DateTime.Now, this.UserAccount.Name);

            result.Object = userMessage;

            return result;
        }

        public virtual BoolGenericResult<UserMessage> ReplyMessage(UserMessage userMessage, string content)
        {
            if (userMessage == null)
            {
                throw new ArgumentException("");
            }

            BoolGenericResult<UserMessage> result = new BoolGenericResult<UserMessage>();
            UserMessage repliedMessage = UserMessageFactory.CreateUserMessage(this.UserAccount, content, userMessage.ID, 0, this.UserAccount, false, DateTime.Now, this.UserAccount.Name);
            result.Object = repliedMessage;
            userMessage.Reply = userMessage.Reply + 1;

            return result;
        }

        public virtual BoolGenericResult<Note> SendNote(
                                                    string title,
                                                    string content,
                                                    InformationIdentifier.NoteType type,
                                                    IList<NoteReceiver> noteReceivers)
        {
            if (noteReceivers == null)
            {
                throw new ArgumentException("");
            }

            BoolGenericResult<Note> result = new BoolGenericResult<Note>();

            Note note = NoteFactory.CreateNote(title, content, type, this.UserAccount, false, noteReceivers, this.UserAccount.Name);
            result.Object = note;

            return result;
        }
    }
}
